#ifndef __QTCH_IOMANAGER_H__
#define __QTCH_IOMANAGER_H__

#include<sys/epoll.h>


#include "scheduler.h"
#include "timer.h"

namespace qtch{

class IOManager :public Scheduler, public TimerManager{
public:
    typedef std::shared_ptr<IOManager> ptr;
    typedef RWMutex RWMutexType;
    IOManager(size_t threads = 1, bool use_caller = false, const std::string & name = "");
    ~IOManager();
    enum Event{
        //无事件
        None    = 0x0,
        // 读事件(EPOLLIN)
        READ    = 0x1,
        // 写事件(EPOLLOUT)
        WRITE   = 0x4
    };

    int addEvent(int fd, Event event, std::function<void()> cb = nullptr);
    bool delEvent(int fd, Event event);
    bool cancelEvent(int fd, Event event);
    bool delEventAll(int fd);
    bool cancelEventAll(int fd);
    static IOManager* getThis();

protected:
    void tickle() override;
    void idle() override;
    bool stopping() override;
    void contextResize(size_t size);
    void onTimerInsertedAtFront() override;
    bool stopping(uint64_t& next_timeout);

private:
    bool _delEvent(int fd,Event event,bool run);
    struct FdContext{
        typedef Mutex MutexType;

        struct EventContext{
            Scheduler* scheduler = nullptr;
            Fiber::ptr fiber = nullptr;
            std::function<void()> cb;
        };

        EventContext& getContext(Event event);
        void resetContext(Event event);
        void triggerEvent(Event event);

        EventContext read;
        EventContext write;
        int fd = -1;
        Event events = None;
        MutexType mutex;
    };

    int m_epfd;
    int m_tickleFds[2];
    std::atomic<size_t> m_pendingEventCount = {0};
    std::vector<FdContext *> m_fdContexts;
    RWMutexType m_mutex;
    
};


}





#endif